MainWindowCs.xaml.cs
Language: C#
Last Modified: 2020-06-27 1:58:33 PM UTC
File Size: 6680 bytes
Last Modified: 2020-06-27 1:58:33 PM UTC
File Size: 6680 bytes
http://www.penguinstew.ca/example/randomorder/MainWindowCs.xaml.cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Threading;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Threading;
namespace RandomOrderCs
{
/// <summary>
/// Random Order program C# version
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
#region constant
// The number of numbers to generate
private const int COUNT = 10000;
#endregion
#region INotifyPropertyChanged interface
//Event called when bound properties are changed
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region private variables
//The private field for the ProgressValue property
private int progressValue = 0;
//The private field for the StatusLabel property
private string statusContent = "Ready";
//Bool set when program is clossing
private bool abort = false;
#endregion
#region properties
//The collection bound to the item source for the listBox
public ObservableCollection<string> numbersListSource { get; set; }
//The int bound to the value attribute of the progress bar
public int ProgressValue
{
get { return progressValue; }
set
{
progressValue = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("ProgressValue"));
}
}
}
//The string bound to the Content attribute of the status label
public string StatusContent
{
get { return statusContent; }
set
{
statusContent = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("StatusContent"));
}
}
}
#endregion
#region constructor
/// <summary>
/// Constructor for the MainWindow class
/// </summary>
public MainWindow()
{
InitializeComponent();
//Setup listBox binding
numbersListSource = new ObservableCollection<string>();
numberList.ItemsSource = numbersListSource;
}
#endregion
#region event handlers
/// <summary>
/// Called when the user clicks on the generate button
/// </summary>
/// <param name="sender">Object sending the event</param>
/// <param name="e">RoutedEventArgs for the event</param>
private void generateButton_Click(object sender, RoutedEventArgs e)
{
//Set status and disable button
generateButton.IsEnabled = false;
StatusContent = "Generating...";
numbersListSource.Clear();
//Start bacground thread to generate numbers
Thread workerThread = new Thread(() => this.generateNumbers());
workerThread.IsBackground = true;
workerThread.Start();
}
/// <summary>
/// Called when the program is clossed
/// </summary>
/// <param name="sender">Object sending the event</param>
/// <param name="e">CancelEventArgs for the event</param>
private void window_Closing(object sender, CancelEventArgs e)
{
//Set the variable to indicate to the background thread that the program is closing
abort = true;
}
#endregion
#region worker methods
/// <summary>
/// Generates a series of numbers in random order and adds them to the listBox
/// </summary>
private void generateNumbers()
{
List<int> numbers = new List<int>(COUNT);
int progressSpace = COUNT / 100;
int progressAmmount = 1;
int sum = 0;
int expectedSum = COUNT * (COUNT + 1) / 2;
Random random = new Random();
DateTime startTime = DateTime.Now;
Action action;
//Set progressAmount if progressSpace is 0
if (progressSpace == 0)
{
progressSpace = 1;
progressAmmount = 100 / COUNT;
}
//Populate list
for (int i = 0; i < COUNT; i++)
{
numbers.Add(i + 1);
}
for (int i = 0; i < COUNT; i++)
{
//If program is aborted return so the thread can close properly
if (abort)
{
return;
}
//Generate a random index
int index = random.Next(0, numbers.Count);
//Get the UI thread to add the number at the generated index to the list
action = new Action(() =>
{
numbersListSource.Add(numbers[index].ToString());
});
this.Dispatcher.Invoke(action, DispatcherPriority.ApplicationIdle);
//Add the number to the sum
sum += numbers[index];
//Remove the number from the list
numbers.RemoveAt(index);
//Update the progress bar
if (i % progressSpace == 0)
{
action = new Action(() =>
{
ProgressValue += progressAmmount;
});
this.Dispatcher.Invoke(action, DispatcherPriority.ApplicationIdle);
}
}
DateTime endTime = DateTime.Now;
//Reset the view and display a message box with the ressults
action = new Action(() =>
{
ProgressValue = 0;
generateButton.IsEnabled = true;
StatusContent = "Done";
MessageBox.Show(String.Format("Sum of numbers = {0} \nExpected sum = {1} \nDifference = {2} \nElapsed time = {3} s"
, sum, expectedSum, expectedSum - sum, endTime.Subtract(startTime).TotalSeconds));
});
this.Dispatcher.Invoke(action, DispatcherPriority.ApplicationIdle);
}
#endregion
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210